package com.ecoolex.cms.system.admin.graphql;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.lang.NonNull;

import com.ecoolex.cms.system.admin.core.AdminConstant;
import com.ecoolex.cms.system.admin.util.VRNaviPathUtil;
import com.ecoolex.cms.system.entity.VRScene;
import com.ecoolex.cms.system.entity.VRSceneHotspot;
import com.ecoolex.cms.system.entity.VRSceneHotspotParam;
import com.ecoolex.cms.system.enums.VRSceneStatus;
import com.ecoolex.cms.system.pojo.AddVRSceneDTO;
import com.ecoolex.cms.system.pojo.AddVRSceneHotspotDTO;
import com.ecoolex.cms.system.pojo.EditVRSceneDTO;
import com.ecoolex.cms.system.pojo.EditVRSceneHotspotDTO;
import com.ecoolex.cms.system.ws.CmsSystemService;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.google.common.collect.Lists;

@GraphQL2Module(type = Type.Admin, description = "vr场景管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = VRSceneGraphql.AUTH, name = "vr场景功能")
public class VRSceneGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-VR-SCENE";
	
	// 查询默认配置
	// 修改默认配置
	
	// 查询场景(根据userId) 分页
	// 编辑场景
	// 删除场景
	// 强制上线
	// 强制下线
	// 查询热点
	// 编辑热点
	// 删除热点

	@Reference
	private CmsSystemService service;

	@TypeField(type = VRScene.class, field = "canEdit", description = "是否能编辑")
	public boolean canEdit(@Source VRScene scene) {
//		return Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
//				|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real());
		return true;
	}

	@TypeField(type = VRScene.class, field = "canOnline", description = "是否能上线")
	public boolean canRelease(@Source VRScene scene) {
		return Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
				|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real());
	}

	@TypeField(type = VRScene.class, field = "canOffline", description = "是否能下线")
	public boolean canOffline(@Source VRScene scene) {
		return Check.eq(scene.getStatus(), VRSceneStatus.ONLINE.real());
	}

	@TypeField(type = VRScene.class, field = "canDeleted", description = "是否能删除")
	public boolean canDeleted(@Source VRScene scene) {
		return Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
				|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real());
	}

	@TypeField(type = VRScene.class, field = "countNaviPath", description = "导航路径数量")
	public Long countNaviPath(@Source VRScene scene) {
		return service.countVRNaviPathByBySceneId(scene.getSceneId());
	}

	@TypeField(type = VRScene.class, field = "hotspotList", description = "热点信息")
	public List<VRSceneHotspot> vrsceneHotspotList(@Source VRScene scene) {
		return service.queryVRSceneHotspotBySceneId(scene.getSceneId());
	}

	@TypeField(type = VRSceneHotspot.class, field = "scene", description = "场景")
	public VRScene vrsceneHotspotList(@Source VRSceneHotspot hotspot, AdminMemberAuthority user) {
		return service.getVRSceneById(user.userId(), hotspot.getSceneId());
	}

	@TypeField(type = VRSceneHotspot.class, field = "canEdit", description = "是否能编辑")
	public boolean canEdit(@Source VRSceneHotspot hotspot) {
//		return Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
//				|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real());
		return true;
	}

	@TypeField(type = VRSceneHotspot.class, field = "canDeleted", description = "是否能删除")
	public boolean canDeleted(@Source VRSceneHotspot hotspot, AdminMemberAuthority user) {
		VRScene scene = service.getVRSceneById(user.userId(), hotspot.getSceneId());
		return Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
				|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real());
	}

	@TypeField(type = VRSceneHotspot.class, field = "paramList", description = "参数列表")
	public List<VRSceneHotspotParam> vrSceneHotspotParamList(@Source VRSceneHotspot hotspot, AdminMemberAuthority user) {
		return service.queryVRSceneHotspotParamByHotspot(hotspot.getHotspotId());
	}

	@QueryField(field = "vrSceneList", description = "场景列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-QUERY", name = "场景列表")
	public Pagination<VRScene> queryVRScene(String sceneName, Integer[] status, @NonNull Page page,
			AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-QUERY");
		return service.queryVRScene(user.userId(), sceneName, status, page);
	}

	@QueryField(field = "vrScene", description = "场景详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-GET", name = "场景详情")
	public VRScene getVRSceneById(@NonNull Integer sceneId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-GET");
		return service.getVRSceneById(user.userId(), sceneId);
	}

	@MutationField(field = "addVRScene", description = "添加vr场景")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-ADD", name = "添加VR场景")
	public VRScene addVRScene(@NonNull AddVRSceneDTO add, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-ADD");

		Assert.isTrue(Check.notNullOrTrimEmpty(add.getSceneName()), ResultCode.VERIFY.build(1), "名称不能为空");
		Assert.isTrue(Check.isRangeWithin(add.getSceneName().length(), 2, 30), ResultCode.VERIFY.build(2),
				"名称需在2-30个字符之间");

		add.setUserId(user.userId());

		return service.addVRScene(add, AdminConstant.PROJECT_ADMIN_NAME);
	}

	@MutationField(field = "editVRScene", description = "编辑vr场景")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-EDIT", name = "编辑VR场景")
	public VRScene editVRScene(@NonNull EditVRSceneDTO edit, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-EDIT");

		Assert.isTrue(Check.notNullOrTrimEmpty(edit.getSceneName()), ResultCode.VERIFY.build(1), "名称不能为空");
		Assert.isTrue(Check.isRangeWithin(edit.getSceneName().length(), 2, 30), ResultCode.VERIFY.build(2),
				"名称需在2-30个字符之间");
		Assert.isTrue(Check.notNull(edit.getSceneId()), ResultCode.VERIFY.build(3), "场景Id为空");

		VRScene old = service.getVRSceneById(user.userId(), edit.getSceneId());
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(4), "该用户没有此数据");

//		Assert.isTrue(
//				Check.eq(old.getStatus(), VRSceneStatus.EDIT.real())
//						|| Check.eq(old.getStatus(), VRSceneStatus.OFFLINE.real()),
//				ResultCode.VERIFY.build(5), "该状态不能编辑");

		edit.setUserId(user.userId());

		return service.editVRScene(edit, AdminConstant.PROJECT_ADMIN_NAME);
	}

	@MutationField(field = "deletedVRScene", description = "删除vr场景")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-DEL", name = "删除VR场景")
	public Boolean deletedVRScene(@NonNull Integer sceneId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-DEL");
		Assert.isTrue(Check.notNull(sceneId), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");

		Assert.isTrue(
				Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
						|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real()),
				ResultCode.VERIFY.build(5), "该状态不能删除");

		service.deleteVRScene(scene, AdminConstant.PROJECT_ADMIN_NAME);
		return true;
	}

	@MutationField(field = "onlineVRScene", description = "上线vr场景")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-ONLINE", name = "上线VR场景")
	public Boolean onlineVRScene(@NonNull Integer sceneId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-ONLINE");
		Assert.isTrue(Check.notNull(sceneId), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");

		Assert.isTrue(
				Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
						|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real()),
				ResultCode.VERIFY.build(5), "该状态不能上线");

		service.online(user.userId(), sceneId, AdminConstant.PROJECT_ADMIN_NAME);
		return true;
	}

	@MutationField(field = "offlineVRScene", description = "下线vr场景")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-OFFLINE", name = "下线VR场景")
	public Boolean offlineVRScene(@NonNull Integer sceneId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-OFFLINE");
		Assert.isTrue(Check.notNull(sceneId), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");

		Assert.isTrue(Check.eq(scene.getStatus(), VRSceneStatus.ONLINE.real()), ResultCode.VERIFY.build(5), "该状态不能下线");

		service.offline(user.userId(), sceneId, AdminConstant.PROJECT_ADMIN_NAME);
		return true;
	}

	@QueryField(field = "vrSceneHotspotList", description = "场景热点列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-QUERY", name = "查询场景热点列表")
	public Pagination<VRSceneHotspot> queryHotspot(@NonNull Integer sceneId, String hotspotName, @NonNull Page page,
			AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-QUERY");
		Assert.isTrue(Check.notNull(sceneId), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");

		return service.queryVRSceneHotspot(sceneId, hotspotName, page);
	}

	@QueryField(field = "vrSceneHotspotAllList", description = "场景全部热点列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-QUERY-ALL", name = "查询场景全部热点列表")
	public List<VRSceneHotspot> queryAllHotspot(@NonNull Integer sceneId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-QUERY-ALL");
		Assert.isTrue(Check.notNull(sceneId), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");

		return service.queryVRSceneHotspotBySceneId(sceneId);
	}

	@QueryField(field = "vrSceneHotspot", description = "场景热点详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-GET", name = "获取场景热点详情")
	public VRSceneHotspot getHotspotById(@NonNull Integer hotspotId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-GET");
		Assert.isTrue(Check.notNull(hotspotId), ResultCode.VERIFY.build(1), "场景热点Id为空");

		VRSceneHotspot hotspot = service.getVRSceneHotspotById(hotspotId);
		if (Check.notNull(hotspot)) {
			VRScene scene = service.getVRSceneById(user.userId(), hotspot.getSceneId());
			Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此数据");
		}

		return hotspot;
	}

	@MutationField(field = "addVrSceneHotspot", description = "添加vr场景热点")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-ADD", name = "添加vr场景热点")
	public VRSceneHotspot addHotspot(@NonNull AddVRSceneHotspotDTO add, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-ADD");
		// 检查场景权限
		Assert.isTrue(Check.notNull(add.getSceneId()), ResultCode.VERIFY.build(1), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), add.getSceneId());
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(2), "该用户没有此场景");

		return service.addVRSceneHotspot(add,
				Check.isNull(add.getParamList()) ? Lists.newArrayList()
						: add.getParamList().stream().map(self -> self).collect(Collectors.toList()),
				AdminConstant.PROJECT_ADMIN_NAME);
	}

	@MutationField(field = "editVRSceneHotspot", description = "编辑vr场景热点")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-EDIT", name = "编辑vr场景热点")
	public VRSceneHotspot editVRSceneHotspot(@NonNull EditVRSceneHotspotDTO edit, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-EDIT");
		Assert.isTrue(Check.notNull(edit.getHotspotId()), ResultCode.VERIFY.build(1), "场景热点Id为空");
		VRSceneHotspot old = service.getVRSceneHotspotById(edit.getHotspotId());
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(2), "场景热点为空");

		Assert.isTrue(Check.notNull(old.getSceneId()), ResultCode.VERIFY.build(3), "场景Id为空");
		VRScene scene = service.getVRSceneById(user.userId(), old.getSceneId());
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(4), "该用户没有此场景");

		return service.editVRSceneHotspot(edit,
				Check.isNull(edit.getParamList()) ? Lists.newArrayList()
						: edit.getParamList().stream().map(self -> self).collect(Collectors.toList()),
				AdminConstant.PROJECT_ADMIN_NAME);
	}

	@MutationField(field = "deleteVrSceneHotspot", description = "删除vr场景热点")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-HOTSPOT-DEL", name = "删除vr场景热点")
	public Boolean deleteHotspot(@NonNull Integer hotspotId, AdminMemberAuthority user) {
		user.assertAuth(AUTH + "-HOTSPOT-DEL");
		Assert.isTrue(Check.notNull(hotspotId), ResultCode.VERIFY.build(1), "场景热点Id为空");
		VRSceneHotspot hotspot = service.getVRSceneHotspotById(hotspotId);
		Assert.isTrue(Check.notNull(hotspot), ResultCode.VERIFY.build(2), "场景热点为空");
		VRScene scene = service.getVRSceneById(user.userId(), hotspot.getSceneId());
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(3), "该用户没有此数据");
		Assert.isTrue(
				Check.eq(scene.getStatus(), VRSceneStatus.EDIT.real())
						|| Check.eq(scene.getStatus(), VRSceneStatus.OFFLINE.real()),
				ResultCode.VERIFY.build(4), "场景热点不能删除");

		service.deleteVRSceneHotspotById(hotspotId, AdminConstant.PROJECT_ADMIN_NAME);
		return true;
	}

	@MutationField(field = "uploadVRNaviPath", description = "上传vr导航路径")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH + "-NAVIPATH-UPLOAD", name = "上传vr导航路径")
	public Boolean uploadVRNaviPath(@NonNull Integer sceneId, @NonNull String xml, AdminMemberAuthority user)
			throws Exception {
		user.assertAuth(AUTH + "-NAVIPATH-UPLOAD");
		VRScene scene = service.getVRSceneById(user.userId(), sceneId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(1), "场景为空");

		return service.updateVRNaviPath(scene, VRNaviPathUtil.read(xml), user.userName());
	}

	@QueryField(field = "shortestVrPath", description = "搜索Vr路径")
	public String shortestVrPath(@NonNull String openId, @NonNull String start, @NonNull String end) {
		VRScene scene = service.getVRSceneByOpenId(openId);
		Assert.isTrue(Check.notNull(scene), ResultCode.VERIFY.build(1), "场景为空");
		Assert.isTrue(Check.eq(scene.getStatus(), VRSceneStatus.ONLINE.real()), ResultCode.VERIFY.build(2), "非上线状态");

		return VRNaviPathUtil.shortestPath(service.queryVRNaviPathBySceneId(scene.getSceneId()), start, end);
	}
	
}
